home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
archiver
/
zoo21src.zoo
/
zoodel.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-07-24
|
10KB
|
307 lines
#ifndef LINT
/* @(#) zoodel.c 2.19 88/02/06 21:23:36 */
/*$Source: g:/newzoo\RCS\zoodel.c,v $*/
/*$Id: zoodel.c,v 1.2 1991/07/24 23:56:54 bjsjr Rel $*/
static char sccsid[]="$Source: g:/newzoo\RCS\zoodel.c,v $\n\
$Id: zoodel.c,v 1.2 1991/07/24 23:56:54 bjsjr Rel $";
#endif /* LINT */
/*
Copyright (C) 1986, 1987 Rahul Dhesi -- All rights reserved
(C) Copyright 1988 Rahul Dhesi -- All rights reserved
*/
#include "options.h"
/* Deletes or undeletes entries from an archive. choice=1 requests
deletion and choice=0 requests undeletion. */
#include "zoo.h"
#include "portable.h"
#ifndef OK_STDIO
#include <stdio.h>
#define OK_STDIO
#endif
#include "various.h" /* may not be needed */
#include "zooio.h"
#include "zoofns.h"
#include "errors.i"
#ifndef NOSIGNAL
#include <signal.h>
#endif
int needed PARMS((char *, struct direntry *, struct zoo_header *));
int ver_too_high PARMS((struct zoo_header *));
extern int quiet;
void zoodel (zoo_path, option, choice)
char *zoo_path;
char *option;
int choice;
{
#ifndef NOSIGNAL
T_SIGNAL (*oldsignal)(); /* to save previous SIGINT handler */
#endif
int delcount = 0; /* how many entries we [un]deleted */
char matchname[PATHSIZE]; /* will hold full pathname */
register ZOOFILE zoo_file;
struct zoo_header zoo_header;
struct direntry direntry;
unsigned int latest_date = 0; /* so we can set time of archive later */
unsigned int latest_time = 0;
int pack = 0; /* pack after deletion? */
int file_deleted = 0; /* any files deleted? */
int one = 0; /* del/undel one file only */
int done; /* loop control */
int action; /* delete/undelete or adjust generation */
int subopt; /* sub option to action */
long gencount; /* generation count */
int doarchive = 0; /* whether to adjust archive gen count */
unsigned valtoshow; /* value to show in informative message */
int dodel = 0; /* selection of deleted files */
int selected; /* if current direntry selected */
/* values for action */
#define NO_ACTION 0 /* nothing */
#define DEL_UNDEL 1 /* delete or undelete file */
#define ADJ_LIM 2 /* adjust generation limit */
#define ADJ_GCNT 3 /* adjust generation count */
#define GEN_ON 4 /* turn on generations */
#define GEN_OFF 5 /* turn off generations */
/* values for subopt */
#define SET 0
#define INC 1
action = NO_ACTION;
if (*option == 'g') {
while (*(++option)) {
switch (*option) {
case 'A': doarchive = 1; break;
case 'q': quiet++; break;
case 'l': action = ADJ_LIM; break;
case 'c': action = ADJ_GCNT; break;
case '=':
subopt = SET; gencount = calc_ofs (++option);
if (action == ADJ_GCNT && gencount == 0)
prterror ('f', "Generation count must be nonzero.\n");
goto opts_done;
case '+':
if (action == NO_ACTION) {
if (option[1] =='\0') {
action = GEN_ON;
goto opts_done;
} else
prterror ('f', garbled);
} else {
subopt = INC; gencount = calc_ofs (++option);
goto opts_done;
}
case '-':
if (action == NO_ACTION) {
if (option[1] =='\0') {
action = GEN_OFF;
goto opts_done;
} else
prterror ('f', garbled);
} else {
subopt = INC; gencount = - calc_ofs (++option);
goto opts_done;
}
case 'd':
dodel++; break;
default:
prterror ('f', garbled);
} /* end switch */
} /* end while */
/* if normal exit from while loop, it means bad command string */
prterror ('f', garbled);
opts_done: /* jump here from exit in while loop above */
if (action == NO_ACTION)
prterror ('f', garbled);
} else {
action = DEL_UNDEL;
while (*(++option)) {
switch (*option) {
case 'P': pack++; break; /* pack after adding */
case 'q': quiet++; break; /* be quiet */
case '1': one++; break; /* del or undel only one file */
default:
prterror ('f', inv_option, *option);
}
} /* end while */
}
/* Open archive for read/write/binary access. It must already exist */
if ((zoo_file = zooopen (zoo_path, Z_RDWR)) == NOFILE) {
prterror ('f', could_not_open, zoo_path);
}
/* read archive header */
frd_zooh (&zoo_header, zoo_file);
if ((zoo_header.zoo_start + zoo_header.zoo_minus) != 0L)
prterror ('f', failed_consistency);
if (ver_too_high (&zoo_header))
prterror ('f', wrong_version, zoo_header.major_ver, zoo_header.minor_ver);
if (doarchive) { /* manipulate archive gen val */
unsigned zoo_date, zoo_time;
#ifdef GETUTIME
getutime (zoo_path, &zoo_date, &zoo_time); /* save archive timestamp */
#else
gettime (zoo_file, &zoo_date, &zoo_time);
#endif
if (zoo_header.type == 0)
prterror ('f', packfirst);
if (action == ADJ_LIM) {
unsigned newgencount;
if (subopt == SET)
newgencount = (unsigned) gencount;
else /* INC */
newgencount = (zoo_header.vdata & VFL_GEN) + (unsigned) gencount;
newgencount &= VFL_GEN; /* reduce to allowed bits */
zoo_header.vdata &= (~VFL_GEN);
zoo_header.vdata |= newgencount;
prterror ('M', "Archive generation limit is now %u\n", newgencount);
} else if (action == GEN_ON) {
zoo_header.vdata |= VFL_ON;
prterror ('M', "Archive generations on\n");
} else if (action == GEN_OFF) {
zoo_header.vdata &= (~VFL_ON);
prterror ('M', "Archive generations off\n");
} else
prterror ('f', garbled);
zooseek (zoo_file, 0L, 0); /* back to begining of file */
fwr_zooh (&zoo_header, zoo_file);
#ifdef NIXTIME
zooclose (zoo_file);
setutime (zoo_path, zoo_date, zoo_time); /* restore archive timestamp */
#else
settime (zoo_file, zoo_date, zoo_time);
zooclose (zoo_file);
#endif
return;
}
zooseek (zoo_file, zoo_header.zoo_start, 0); /* seek to where data begins */
done = 0; /* loop not done yet */
while (1) {
long this_dir_offset;
this_dir_offset = zootell (zoo_file); /* save pos'n of this dir entry */
frd_dir (&direntry, zoo_file);
if (direntry.zoo_tag != ZOO_TAG) {
prterror ('f', bad_directory);
}
if (direntry.next == 0L) { /* END OF CHAIN */
break; /* EXIT on end of chain */
}
/* select directory entry if it matches criteria */
selected = (
(action == DEL_UNDEL && direntry.deleted != choice)
||
(action != DEL_UNDEL &&
(dodel && direntry.deleted ||
(dodel < 2 && !direntry.deleted))
)
);
/* WARNING: convention of choice=1 for deleted entry must be same as
in direntry definition in zoo.h */
/* Test for "done" so if "one" option requested, [un]del only 1 file */
/* But we go through the whole archive to adjust archive time */
strcpy (matchname, fullpath (&direntry)); /* get full pathname */
if (zoo_header.vdata & VFL_ON)
add_version (matchname, &direntry); /* add version suffix */
if (!done && selected && needed(matchname, &direntry, &zoo_header)) {
prterror ('m', "%-14s -- ", matchname);
delcount++;
if (action == DEL_UNDEL) {
direntry.deleted = choice;
if (choice)
file_deleted++; /* remember if any files actually deleted */
} else { /* ADJ_LIM or ADJ_GENCNT */
if (direntry.vflag & VFL_ON) { /* skip if no versions */
if (action == ADJ_LIM) {
unsigned newgencount;
if (subopt == SET)
newgencount = (unsigned) gencount;
else /* INC */
newgencount =
(int) (direntry.vflag & VFL_GEN) + (int) gencount;
newgencount &= VFL_GEN;
direntry.vflag &= (~VFL_GEN);
direntry.vflag |= newgencount;
valtoshow = newgencount;
} else { /* ADJ_GCNT */
if (subopt == SET)
direntry.version_no = (unsigned) gencount;
else /* INC */
direntry.version_no +